﻿
////////////////////////////////////////////////////////////////
///
/// File: BodyToken.cs
/// Author: Lucio Davide Spano
/// Last update: 27 July 2012
/// Description: This class represents the token used 
///              by the Kinect platform during the temporal
///              expression execution
/// To do: 
/// ------------------------------------------------------------
/// Copyright (c) 2012 Lucio Davide Spano 
///                     (lucio.davide.spano@isti.cnr.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------
////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;

using GestIT;

namespace BodyGestIT
{
    public class BodyToken : Token
    {
        /// <summary>
        /// buffer for all the tracked skeletons
        /// </summary>
        private ClonableSkeleton[,] samples;

        /// <summary>
        /// single skeleton buffer length, set when the token is created
        /// </summary>
        private int capacity;

        /// <summary>
        /// current indices for all skeleton buffers
        /// </summary>
        private int[] index;
       
        public int Id { get; set; }

        public BodyToken()
            : base()
        {
            samples = new ClonableSkeleton[BodyEmitter.skeletonCount, 1];
            index = new int[BodyEmitter.skeletonCount];
            capacity = 1;
            initializeIndices();
        }

        public BodyToken(int bufferedPosition)
            : base()
        {
            samples = new ClonableSkeleton[BodyEmitter.skeletonCount, bufferedPosition];
            index = new int[BodyEmitter.skeletonCount];
            this.capacity = bufferedPosition;
            initializeIndices();
        }

        public void Save(ClonableSkeleton s)
        {
            ClonableSkeleton cl = null;
            int i = s.TrackingId % BodyEmitter.skeletonCount;

            if (samples[i, index[i]] == null)
            {
                // the buffer slot is empty, 
                // create a new skeleton for buffering
                cl = new ClonableSkeleton();
                cl.UpdateFromSkeleton(s);
                samples[i, index[i]] = cl;
            }
            else
            {
                // reuse an existing skeleton
                cl = samples[i, index[i]];
                cl.UpdateFromSkeleton(s);
            }

            // update the buffer index for the considered skeleton
            index[i] = (index[i] + 1) % capacity;

            //if (samplesCount == capacity)
            //{
            //    // reuse an existing skeleton
            //    cl = samples[i, index];
            //    cl.UpdateFromSkeleton(s);

            //}
            //else
            //{
            //    // create a new one
            //    cl = new ClonableSkeleton();
            //    cl.UpdateFromSkeleton(s);
            //    samples[i, index] = cl;
            //    samplesCount++;
            //}
            //index = (index + 1) % samples.Length;
        }

        public ClonableSkeleton GetSkeleton(int skeletonId, int pos)
        {
            int i = skeletonId % BodyEmitter.skeletonCount;
            if (pos >= capacity)
            {
                return null;
            }

            return samples[i, Math.Abs(index[i] - pos - 1) % capacity];
        }

        private void initializeIndices()
        {
            for (int i = 0; i < index.Length; i++)
            {
                index[i] = 0;
            }
        }
    }
}
